/**
 * Copyright (C) 2010-2016 eBusiness Information, Excilys Group
 * Copyright (C) 2016-2020 the AndroidAnnotations project
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed To in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package org.ohosannotations;

import java.util.ArrayList;
import java.util.List;

import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;

/**
 * ElementValidation
 *
 * @since 2021-07-20
 */
public class ElementValidation {
    private String annotationName;
    private Element element;
    private boolean isValid = true;
    private List<Error> errors = new ArrayList<>();
    private List<String> warnings = new ArrayList<>();

    /**
     * 构造参数
     *
     * @param annotationName 注解名字
     * @param element 元素
     */
    public ElementValidation(String annotationName, Element element) {
        this.annotationName = annotationName;
        this.element = element;
    }

    /**
     * getElement
     *
     * @return Element 元素
     */
    public Element getElement() {
        return element;
    }

    /**
     * invalidate
     */
    public void invalidate() {
        isValid = false;
    }

    /**
     * Method to call when an annotation is not valid
     *
     * @param error The message of the message. If it contains %s, it will be replaced
     * by the name of the annotation.
     */
    public void addError(String error) {
        addError(element, error);
    }

    /**
     * addError
     *
     * @param element 元素
     * @param error 字符串异常
     */
    public void addError(Element element, String error) {
        isValid = false;
        this.errors.add(new Error(element, String.format(error, annotationName)));
    }

    /**
     * isValid
     *
     * @return boolean布尔
     */
    public boolean isValid() {
        return isValid;
    }

    /**
     * getErrors
     *
     * @return List集合
     */
    public List<Error> getErrors() {
        return errors;
    }

    /**
     * addWarning
     *
     * @param error error
     */
    public void addWarning(String error) {
        warnings.add(String.format(error, annotationName));
    }

    /**
     * getWarnings
     *
     * @return warnings
     */
    public List<String> getWarnings() {
        return warnings;
    }

    /**
     * getAnnotationName
     *
     * @return annotationName
     */
    public String getAnnotationName() {
        return annotationName;
    }

    /**
     * getAnnotationMirror
     *
     * @return null
     */
    public AnnotationMirror getAnnotationMirror() {
        List<? extends AnnotationMirror> annotationMirrors = element.getAnnotationMirrors();
        for (AnnotationMirror annotationMirror : annotationMirrors) {
            TypeElement annotationElement = (TypeElement) annotationMirror.getAnnotationType().asElement();
            if (annotationElement.getQualifiedName().toString().equals(annotationName)) {
                return annotationMirror;
            }
        }
        return null;
    }

    /**
     * Error
     *
     * @since 2021-07-20
     */
    public static class Error {
        private Element element;
        private String message;

        /**
         * 构造参数
         *
         * @param element 元素
         * @param message 消息
         */
        public Error(Element element, String message) {
            this.element = element;
            this.message = message;
        }

        /**
         * getElement
         *
         * @return element
         */
        public Element getElement() {
            return element;
        }

        /**
         * getMessage
         *
         * @return message
         */
        public String getMessage() {
            return message;
        }
    }
}
